package com.mycompany.myapp.web.rest.base;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mycompany.myapp.domain.CommonTable;
import com.mycompany.myapp.repository.CommonTableRepository;
import com.mycompany.myapp.service.CommonTableQueryService;
import com.mycompany.myapp.service.CommonTableService;
import com.mycompany.myapp.service.criteria.CommonTableCriteria;
import com.mycompany.myapp.service.dto.CommonTableDTO;
import com.mycompany.myapp.util.ExportUtil;
import com.mycompany.myapp.util.web.IPageUtil;
import com.mycompany.myapp.util.web.PageableUtils;
import com.mycompany.myapp.web.rest.errors.BadRequestAlertException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
import tech.jhipster.web.util.HeaderUtil;
import tech.jhipster.web.util.ResponseUtil;

// jhipster-needle-add-import - JHipster will add getters and setters here, do not remove

/**

 * 管理实体{@link com.mycompany.myapp.domain.CommonTable}的REST Controller。
 */

public class CommonTableBaseResource {

    protected final Logger log = LoggerFactory.getLogger(CommonTableBaseResource.class);

    protected static final String ENTITY_NAME = "modelConfigCommonTable";

    @Value("${jhipster.clientApp.name}")
    protected String applicationName;

    protected final CommonTableService commonTableService;

    protected final CommonTableRepository commonTableRepository;

    protected final CommonTableQueryService commonTableQueryService;

    public CommonTableBaseResource(
        CommonTableService commonTableService,
        CommonTableRepository commonTableRepository,
        CommonTableQueryService commonTableQueryService
    ) {
        this.commonTableService = commonTableService;
        this.commonTableRepository = commonTableRepository;
        this.commonTableQueryService = commonTableQueryService;
    }

    /**
     * {@code POST  /common-tables} : Create a new commonTable.
     *
     * @param commonTableDTO the commonTableDTO to create.
     * @return the {@link ResponseEntity} with status {@code 201 (Created)} and with body the new commonTableDTO, or with status {@code 400 (Bad Request)} if the commonTable has already an ID.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PostMapping("/common-tables")
    @ApiOperation(value = "新建关系模型", notes = "创建并返回一个新的关系模型")
    public ResponseEntity<CommonTableDTO> createCommonTable(@Valid @RequestBody CommonTableDTO commonTableDTO) throws URISyntaxException {
        log.debug("REST request to save CommonTable : {}", commonTableDTO);
        if (commonTableDTO.getId() != null) {
            throw new BadRequestAlertException("A new commonTable cannot already have an ID", ENTITY_NAME, "idexists");
        }
        CommonTableDTO result = commonTableService.save(commonTableDTO);
        return ResponseEntity
            .created(new URI("/api/common-tables/" + result.getId()))
            .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

    /**
     * {@code PUT  /common-tables/:id} : Updates an existing commonTable.
     *
     * @param id the id of the commonTableDTO to save.
     * @param commonTableDTO the commonTableDTO to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/common-tables/{id}")
    @ApiOperation(value = "更新关系模型", notes = "根据主键更新并返回一个更新后的关系模型")
    public ResponseEntity<CommonTableDTO> updateCommonTable(
        @PathVariable(value = "id", required = false) final Long id,
        @Valid @RequestBody CommonTableDTO commonTableDTO
    ) throws URISyntaxException {
        log.debug("REST request to update CommonTable : {}, {}", id, commonTableDTO);
        if (commonTableDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (!Objects.equals(id, commonTableDTO.getId())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

        if (!commonTableService.exists(CommonTable::getId, id)) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }

        CommonTableDTO result = commonTableService.save(commonTableDTO);
        return ResponseEntity
            .ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, commonTableDTO.getId().toString()))
            .body(result);
    }

    /**
     * {@code PUT  /common-tables/:copyFromId} : copy from  an existing commonTableId.
     *
     * @param copyFromId the commonTableId to copy.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/common-tables/copy/{copyFromId}")
    public ResponseEntity<CommonTableDTO> updateCommonTable(@PathVariable Long copyFromId) throws URISyntaxException {
        log.debug("REST request to copy CommonTable from id : {}", copyFromId);
        CommonTableDTO result = commonTableService.copyFromId(copyFromId).get();
        return ResponseEntity
            .ok()
            .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, result.getId().toString()))
            .body(result);
    }

    /**
     * {@code GET  /common-tables/entity-name/:entityName} : get the "entityName" commonTable.
     *
     * @param entityName the entityName of the commonTableDTO to retrieve.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the commonTableDTO, or with status {@code 404 (Not Found)}.
     */
    @GetMapping("/common-tables/entity-name/{entityName}")
    public ResponseEntity<CommonTableDTO> getByEntityName(@PathVariable String entityName) {
        log.debug("REST request to get CommonTable by entityName : {}", entityName);
        Optional<CommonTableDTO> commonTableDTO = commonTableService.findOneByEntityName(entityName);
        return ResponseUtil.wrapOrNotFound(commonTableDTO);
    }

    /**
     * {@code PATCH  /common-tables/:id} : Partial updates given fields of an existing commonTable, field will ignore if it is null.
     *
     * @param id the id of the commonTableDTO to save.
     * @param commonTableDTO the commonTableDTO to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 404 (Not Found)} if the commonTableDTO is not found,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @ApiOperation(value = "部分更新关系模型", notes = "根据主键及实体信息实现部分更新，值为null的属性将忽略，并返回一个更新后的关系模型")
    @PatchMapping(value = "/common-tables/{id}", consumes = "application/merge-patch+json")
    public ResponseEntity<CommonTableDTO> partialUpdateCommonTable(
        @PathVariable(value = "id", required = false) final Long id,
        @NotNull @RequestBody CommonTableDTO commonTableDTO
    ) throws URISyntaxException {
        log.debug("REST request to partial update CommonTable partially : {}, {}", id, commonTableDTO);
        if (commonTableDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        if (!Objects.equals(id, commonTableDTO.getId())) {
            throw new BadRequestAlertException("Invalid ID", ENTITY_NAME, "idinvalid");
        }

        if (commonTableRepository.findById(id).isPresent()) {
            throw new BadRequestAlertException("Entity not found", ENTITY_NAME, "idnotfound");
        }

        Optional<CommonTableDTO> result = commonTableService.partialUpdate(commonTableDTO);

        return ResponseUtil.wrapOrNotFound(
            result,
            HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, commonTableDTO.getId().toString())
        );
    }

    /**
     * {@code GET  /common-tables} : get all the commonTables.
     *

     * @param pageable the pagination information.
     * @param criteria the criteria which the requested entities should match.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of commonTables in body.
     */
    @GetMapping("/common-tables")
    @ApiOperation(value = "获取关系模型分页列表", notes = "获取关系模型的分页列表数据")
    public ResponseEntity<List<CommonTableDTO>> getAllCommonTables(
        CommonTableCriteria criteria,
        Pageable pageable,
        @RequestParam(value = "listModelName", required = false) String listModelName,
        @RequestParam(value = "commonQueryId", required = false) Long commonQueryId
    ) throws ClassNotFoundException {
        log.debug("REST request to get CommonTables by criteria: {}", criteria);
        IPage<CommonTableDTO> page;
        if (listModelName != null) {
            page = commonTableQueryService.selectByCustomEntity(listModelName, criteria, null, PageableUtils.toPage(pageable));
        } else {
            page = commonTableQueryService.findByCriteria(criteria, PageableUtils.toPage(pageable));
        }
        HttpHeaders headers = IPageUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page);
        return ResponseEntity.ok().headers(headers).body(page.getRecords());
    }

    /**
     * {@code GET  /common-tables/count} : count all the commonTables.
     *
     * @param criteria the criteria which the requested entities should match.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the count in body.
     */
    @GetMapping("/common-tables/count")
    public ResponseEntity<Long> countCommonTables(CommonTableCriteria criteria) {
        log.debug("REST request to count CommonTables by criteria: {}", criteria);
        return ResponseEntity.ok().body(commonTableQueryService.countByCriteria(criteria));
    }

    /**
     * {@code GET  /common-tables/:id} : get the "id" commonTable.
     *
     * @param id the id of the commonTableDTO to retrieve.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the commonTableDTO, or with status {@code 404 (Not Found)}.
     */
    @GetMapping("/common-tables/{id}")
    @ApiOperation(value = "获取指定主键的关系模型", notes = "获取指定主键的关系模型信息")
    public ResponseEntity<CommonTableDTO> getCommonTable(@PathVariable Long id) {
        log.debug("REST request to get CommonTable : {}", id);
        Optional<CommonTableDTO> commonTableDTO = commonTableService.findOne(id);
        return ResponseUtil.wrapOrNotFound(commonTableDTO);
    }

    /**
     * GET  /common-tables/export : export the commonTables.
     *
     */
    @GetMapping("/common-tables/export")
    @ApiOperation(value = "关系模型EXCEL导出", notes = "导出全部关系模型为EXCEL文件")
    public void exportToExcel(HttpServletResponse response) {
        List<CommonTableDTO> data = commonTableService.findAll(new Page<>(1, Integer.MAX_VALUE)).getRecords();
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("关系模型一览表", "关系模型"), CommonTableDTO.class, data);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String filename = "关系模型_" + sdf.format(new Date()) + ".xlsx";
        try {
            ExportUtil.excel(workbook, filename, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * POST  /common-tables/import : import the commonTables from excel file.
     *
     * @return the ResponseEntity with status 200 (OK) and with body the commonTableDTO, or with status 404 (Not Found)
     */
    @PostMapping("/common-tables/import")
    @ApiOperation(value = "关系模型EXCEL导入", notes = "根据关系模型EXCEL文件导入全部数据")
    public ResponseEntity<Void> exportToExcel(MultipartFile file) throws Exception {
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        params.setHeadRows(1);
        List<CommonTableDTO> list = ExcelImportUtil.importExcel(file.getInputStream(), CommonTableDTO.class, params);
        list.forEach(commonTableService::save);
        return ResponseEntity.ok().build();
    }

    /**
     * {@code DELETE  /common-tables/:id} : delete the "id" commonTable.
     *
     * @param id the id of the commonTableDTO to delete.
     * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
     */
    @DeleteMapping("/common-tables/{id}")
    @ApiOperation(value = "删除一个关系模型", notes = "根据主键删除单个关系模型")
    public ResponseEntity<Void> deleteCommonTable(@PathVariable Long id) {
        log.debug("REST request to delete CommonTable : {}", id);
        commonTableService.delete(id);
        return ResponseEntity
            .noContent()
            .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString()))
            .build();
    }

    /**
     * {@code DELETE  /common-tables} : delete all the "ids" CommonTables.
     *
     * @param ids the ids of the articleDTO to delete.
     * @return the {@link ResponseEntity} with status {@code 204 (NO_CONTENT)}.
     */
    @DeleteMapping("/common-tables")
    @ApiOperation(value = "删除多个关系模型", notes = "根据主键删除多个关系模型")
    public ResponseEntity<Void> deleteCommonTablesByIds(@RequestParam("ids") ArrayList<Long> ids) {
        log.debug("REST request to delete CommonTables : {}", ids);
        if (ids != null) {
            ids.forEach(commonTableService::delete);
        }
        return ResponseEntity
            .noContent()
            .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, (ids != null ? ids.toString() : "NoIds")))
            .build();
    }

    @ApiOperation(value = "查询creator为当前用户的关系模型列表", notes = "查询creator为当前用户的关系模型列表")
    @GetMapping("/common-tables/creator/current-user")
    public ResponseEntity<List<CommonTableDTO>> findByCreatorIsCurrentUser() {
        log.debug("REST request to get CommonTable for current user. ");
        List<CommonTableDTO> result = commonTableService.findByCreatorIsCurrentUser();
        return ResponseEntity.ok(result);
    }

    /**
     * {@code PUT  /common-tables/specified-fields} : Updates an existing commonTable by specified fields.
     *
     * @param commonTableDTOAndSpecifiedFields the commonTableDTO and specifiedFields to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/common-tables/specified-fields")
    @ApiOperation(value = "根据字段部分更新关系模型", notes = "根据指定字段部分更新关系模型，给定的属性值可以为任何值，包括null")
    public ResponseEntity<CommonTableDTO> updateBySpecifiedFields(
        @RequestBody CommonTableDTOAndSpecifiedFields commonTableDTOAndSpecifiedFields
    ) {
        log.debug("REST request to update CommonTableDTO : {}", commonTableDTOAndSpecifiedFields);
        CommonTableDTO commonTableDTO = commonTableDTOAndSpecifiedFields.getCommonTable();
        Set<String> specifiedFields = commonTableDTOAndSpecifiedFields.getSpecifiedFields();
        if (commonTableDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        Optional<CommonTableDTO> result = commonTableService.updateBySpecifiedFields(commonTableDTO, specifiedFields);
        return ResponseUtil.wrapOrNotFound(
            result,
            HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, commonTableDTO.getId().toString())
        );
    }

    /**
     * {@code PUT  /common-tables/specified-field-batch} : batch Updates an existing commonTable by specified field and ids.
     *
     * @param commonTableDTOAndSpecifiedFields the commonTableDTO and specifiedFields to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/common-tables/specified-field-batch")
    @ApiOperation(value = "根据字段部分更新关系模型", notes = "根据指定字段部分更新关系模型，给定的属性值可以为任何值，包括null")
    public ResponseEntity<Void> updateBySpecifiedFieldBatch(
        @RequestBody CommonTableDTOAndSpecifiedFields commonTableDTOAndSpecifiedFields
    ) {
        log.debug("REST request to update CommonTableDTO : {}", commonTableDTOAndSpecifiedFields);
        CommonTableDTO commonTableDTO = commonTableDTOAndSpecifiedFields.getCommonTable();
        if (CollectionUtils.isEmpty(commonTableDTOAndSpecifiedFields.getIds())) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        commonTableService.updateBySpecifiedFieldBatch(
            commonTableDTO,
            commonTableDTOAndSpecifiedFields.getSpecifiedField(),
            commonTableDTOAndSpecifiedFields.getIds()
        );
        return ResponseEntity.ok().build();
    }

    /**
     * {@code PUT  /common-tables/specified-field} : Updates an existing commonTableDTO by specified field.
     *
     * @param commonTableDTOAndSpecifiedFields the commonTableDTO and specifiedFields to update.
     * @return the {@link ResponseEntity} with status {@code 200 (OK)} and with body the updated commonTableDTO,
     * or with status {@code 400 (Bad Request)} if the commonTableDTO is not valid,
     * or with status {@code 500 (Internal Server Error)} if the commonTableDTO couldn't be updated.
     * @throws URISyntaxException if the Location URI syntax is incorrect.
     */
    @PutMapping("/common-tables/specified-field")
    @ApiOperation(value = "更新关系模型单个属性", notes = "根据指定字段更新关系模型，给定的属性值可以为任何值，包括null")
    public ResponseEntity<CommonTableDTO> updateCommonTableBySpecifiedField(
        @RequestBody CommonTableDTOAndSpecifiedFields commonTableDTOAndSpecifiedFields
    ) throws URISyntaxException {
        log.debug("REST request to update commonTableDTO : {}", commonTableDTOAndSpecifiedFields);
        CommonTableDTO commonTableDTO = commonTableDTOAndSpecifiedFields.getCommonTable();
        String fieldName = commonTableDTOAndSpecifiedFields.getSpecifiedField();
        if (commonTableDTO.getId() == null) {
            throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull");
        }
        Optional<CommonTableDTO> result = commonTableService.updateBySpecifiedField(commonTableDTO, fieldName);
        return ResponseUtil.wrapOrNotFound(
            result,
            HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, commonTableDTO.getId().toString())
        );
    }

    // jhipster-needle-rest-resource-add-api - JHipster will add getters and setters here, do not remove

    private static class CommonTableDTOAndSpecifiedFields {

        private CommonTableDTO commonTable;
        private Set<String> specifiedFields;
        private String specifiedField;
        private List<Long> ids;

        private CommonTableDTO getCommonTable() {
            return commonTable;
        }

        private void setCommonTable(CommonTableDTO commonTable) {
            this.commonTable = commonTable;
        }

        private Set<String> getSpecifiedFields() {
            return specifiedFields;
        }

        private void setSpecifiedFields(Set<String> specifiedFields) {
            this.specifiedFields = specifiedFields;
        }

        public String getSpecifiedField() {
            return specifiedField;
        }

        public void setSpecifiedField(String specifiedField) {
            this.specifiedField = specifiedField;
        }

        public void setIds(List<Long> ids) {
            this.ids = ids;
        }

        public List<Long> getIds() {
            return this.ids;
        }
    }
}
